package com.zhangh.summer.admin.support.prometheus.request;

import com.zhangh.summer.admin.support.log.LogRecorder;
import com.zhangh.summer.admin.support.prometheus.MetricsExporter;
import io.prometheus.client.Counter;
import io.prometheus.client.Summary;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @description: prometheus http 监控
 * @author: zhanghui  zhanghlucky@163.com
 * @create: 2020-06-30 10:41
 **/
@Slf4j
public class RequestInterceptor implements HandlerInterceptor {
    private static final String REQ_PARAM_TIMING = "timing";
    private static final String COST_KEY="cost";

    public RequestInterceptor() {

    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setAttribute(REQ_PARAM_TIMING, System.currentTimeMillis());
        return true;
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        Long timingAttr = (Long)request.getAttribute(REQ_PARAM_TIMING);
        long completedTime = System.currentTimeMillis() - timingAttr;
        String handlerLabel = handler.toString();
        if (handler instanceof HandlerMethod) {

            Method method = ((HandlerMethod)handler).getMethod();
            handlerLabel = method.getDeclaringClass().getSimpleName() + "/" + method.getName();
            String uri=request.getRequestURI();
            //记录日志
            MDC.put(COST_KEY,String.valueOf(completedTime));
            LogRecorder.instance()
                    .setKey1(handlerLabel)
                    .setKey2(uri).logger(log)
                    .info("cost:{}",completedTime);
        }
        ((Summary.Child) MetricsExporter.getInstance().getResponseTimeInMs().labels(new String[]{request.getMethod(), handlerLabel, Integer.toString(response.getStatus())})).observe((double)completedTime);
        ((Counter.Child) MetricsExporter.getInstance().getRequestTotal().labels(new String[]{request.getMethod(), handlerLabel, Integer.toString(response.getStatus())})).inc();
    }
}

